本節資源 : (待補)
今天使用到的範例圖來自 : Everything about Framer Motion layout animations - Maxime Heckel's Blog ,之後會補上自己的實作部分,今天小休息一下。另外尷尬的是免費的影片轉檔 10 張扣打被我用光光了... QQ。
碰到網頁 reflow 突然版面會出現跳針、抽蓄的情況,可以試試看其他 layout 屬性來解決。
layout 除了基本直接 layout
單個這樣,它還有不同的值,各司其職。上一篇提到 layout
背後大概做了什麼,歸納一下大概做兩件事 :
也對應到 layout 的其他種類 :
true
: 預設,同時做縮放大小與位移的漸變動畫。position
: 只做位移上的漸變動畫,遇到大小相關會突然直接跳過去size
: 只做縮放大小漸變動畫,遇到位移相關屬性改變會突然直接跳過去<motion.div
layout = "true"
layout ="position"
layout ="size"
/>
可以看到 layout=true
兩件事都有做,position
在一開始放大就跳過去,才做移動;相反的 size 先縮放,而位移變順移了。
不過既然預設 layout
都這麼無敵了,position 跟 size 有何用武之地 ?
官方提到跟 文字有關的元件為了避免被伸縮拉長, position
是最佳的替代屬性。
而在版面上有什麼幫助呢 ? flexbox 是排版聖品,尤其是會自動壓一壓跟自動流向排版,我們只要拿捏好伸縮壓縮比 (glow 、 shrink)跟寫好方向,在不同裝置就可以做出理想的版面。但加上動畫的時候,由於是排版屬性會造成 reflow,像 flex 屬性會根據比例調配剩下的空間或壓縮程度,同時影響到 transform 的 postion 與 scale。
layout=true
,會發現 label 會被伸縮給影響跳了一下,因為 flex 跟剩下的空間壓縮比有關,避免這樣的情形,這時可以改用 position。layout=position
,少掉伸縮的閃爍問題在 React 我們很常會改變節點 render 的狀況 ,例如 :
{isShow ? <div>出來</div> : <div>消失</div> } // 替代另一種元件
{isShow ? <div>出來</div> : null } // 從 Render tree 消失
或是做元件上的替換,前者我們會看到元件 "啪 !" 就不見了,就算用 CSS transition 也變得像跟 display : none
直接消失,而 layoutId
幫助在 節點消失/交換在 Render tree 時到下一個 render 進行動畫。
可以先 參考官方的範例,可以看到 Tab 底下的 underline
是在個別 <li>
元素,但卻又可以在 標籤消失時進行動畫。其原理是先拿 render 之後的元件,並且拷貝上一個消失或交換的元素位置,利用 transform 移到正確 render之後元件該出現的地方。
改變 layout 意味著也可能改變別的元素版面,比如元素消失,底下的元素按照排版流補上。我們知道 layout
先做 transform 位移與縮放,但是實際上最後 render 還是會存在於版面中的實體正確位置,佔據確實的空間,如果有兩個以上的 layout
存在,那 motion 怎麼在原本的排版流 (layout flow) 進行動畫補間排序呢 ?
<LayoutGroup>
就是幫助處理這樣的情形,具體上適用於兩種情境 :
<LayoutGroup>
幫我們加上補間。layoutId
的元件群組分開上面我們提到 layoutId
使得跨元件內部可以漸變同一個元件 layoutId
的動畫補間,但要注意 layoutId
元件是全域的,也就是同時有兩組用到一樣的 layoutId
會導致另一組失靈,而 <layoutGroup>
將個別群組起來並且使用獨特的 id
來辨別避免這個問題發生。
(影片轉換扣打不夠 QQ)
position
與 size
,前者只處理位移,後者只處理縮放大小。layoutId
: 使跨元件的節點可以進行漸變動畫,看起來像共享元件動畫。<layoutGroup>
: 協調多個版面動畫的排版流向或是隔開 layoutId
造成打架的問題。關於 layout
還有另一個實用的場景,會等到 <Reoreder>
元件在一起討論。明天來點會來點輕鬆的介紹 transition
各種 type 屬性的設定值,並且把 motion props 的部份做總結,下一個大章節會是 motion 其他的 component ,包含最大特色的 <AnimatePresence>
。